﻿CREATE FUNCTION [QIC].[Aspect_DEFAULT](@ConfigName VARCHAR(50))
RETURNS TABLE
AS
RETURN
(
	SELECT 
		Aspect.InterfaceId,
		Aspect.InterfaceName,
		Aspect.InterfaceType,
		Aspect.InterfaceSchemaName,
		Aspect.DelegateName,
		Aspect.ActionName,
		Aspect.AspectName,
		Aspect.TokenMap,
		Aspect.AspectId,
		Aspect.AspectType,
		Aspect.AspectReturnToken,
		Aspect.CallFactory,
		ROW_NUMBER() OVER (PARTITION BY Aspect.InterfaceName, Aspect.DelegateName, Aspect.ActionName ORDER BY Aspect.Prio DESC) SortOrder
	FROM 
	(
		SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateName,
			AspectConfig.WhenActionName ActionName,
			Aspect.InterfaceName AspectName,
			Aspect.InterfaceId AspectId,
			AspectConfig.ThenTokenMap TokenMap,
			AspectConfig.ThenReturnToken AspectReturnToken,
			Aspect.InterfaceType AspectType,
			REPLACE(CAST(ISNULL(AspectConfig.ThenCallFactory,Aspect.InterfaceType) AS VARCHAR(50)), ' ', '') CallFactory,
			MAX(AspectConfig.ThenPrio) Prio
		FROM (
			SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateName
			FROM QIC.Delegate_(@ConfigName) Delegate
			GROUP BY 
				Delegate.InterfaceId,
				Delegate.InterfaceName,
				Delegate.InterfaceType,
				Delegate.InterfaceSchemaName,
				Delegate.DelegateName
			UNION ALL
			SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.SchemaName InterfaceSchemaName,
			'' DelegateName
			FROM QIC.Interface_(@ConfigName) Delegate
			GROUP BY 
				Delegate.InterfaceId,
				Delegate.InterfaceName,
				Delegate.InterfaceType,
				Delegate.SchemaName
		) Delegate
		LEFT OUTER JOIN QIC.Config Config
			ON Config.Name = @ConfigName
		INNER JOIN QIC.AspectConfig AspectConfig
			ON (AspectConfig.WhenConfigName IS NULL OR AspectConfig.WhenConfigName = Config.Name)
			AND (AspectConfig.WhenSchemaName IS NULL OR AspectConfig.WhenSchemaName = Delegate.InterfaceSchemaName)
			AND ((AspectConfig.WhenDelegateName IS NULL AND Delegate.DelegateName <> '') OR AspectConfig.WhenDelegateName = Delegate.DelegateName)
			AND (AspectConfig.WhenInterfaceName IS NULL OR AspectConfig.WhenInterfaceName = Delegate.InterfaceName)
			AND (AspectConfig.WhenInterfaceType IS NULL OR AspectConfig.WhenInterfaceType COLLATE DATABASE_DEFAULT = Delegate.InterfaceType COLLATE DATABASE_DEFAULT)
		INNER JOIN QIC.Interface_(@ConfigName) Aspect
			ON Aspect.InterfaceName = AspectConfig.ThenInterfaceName
			AND QIC.AspectAllow(AspectConfig.WhenActionName, Delegate.InterfaceType, Aspect.InterfaceType) = 1
		WHERE (ISNULL(AspectConfig.ThenPrio,0) >= ISNULL(Config.MinPrio,0))
		AND Delegate.InterfaceId <> Aspect.InterfaceId
		GROUP BY
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateName,
			AspectConfig.WhenActionName,
			Aspect.InterfaceName,
			Aspect.InterfaceId,
			AspectConfig.ThenTokenMap,
			AspectConfig.ThenReturnToken,
			AspectConfig.ThenCallFactory,
			Aspect.InterfaceType
	) Aspect
	
);